package com.mingliqiye.minecraft.enchantment.conflict.common;

import static com.mingliqiye.minecraft.enchantment.conflict.common.DataFormat.JSONOBJECTMAPPER;
import static com.mingliqiye.minecraft.enchantment.conflict.common.DataFormat.YALMOBJECTMAPPER;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JavaType;
import com.mingliqiye.utils.StringUtil;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Map;
import org.slf4j.Logger;

public class ConfigManager {

    private final String FILE_NAME = StringUtil.format("{}.yaml", MinecraftMod.MOD_ID);
    private final DefConfig defConfig;

    public static final JavaType MODCONFIGTYPE = JSONOBJECTMAPPER.getTypeFactory().constructMapType(
        Map.class,
        String.class,
        ConfigPair.class
    );

    public static Map<String, ConfigPair> fromyaml(String s) {
        try {
            return YALMOBJECTMAPPER.readValue(s, MODCONFIGTYPE);
        } catch (JsonProcessingException e) {
            throw new RuntimeException(e);
        }
    }

    public static String toyaml(Map<String, ConfigPair> c) {
        try {
            return YALMOBJECTMAPPER.writeValueAsString(c);
        } catch (JsonProcessingException e) {
            throw new RuntimeException(e);
        }
    }

    public static Map<String, ConfigPair> fromjson(String s) {
        try {
            return JSONOBJECTMAPPER.readValue(s, MODCONFIGTYPE);
        } catch (JsonProcessingException e) {
            throw new RuntimeException(e);
        }
    }

    public static String tojson(Map<String, ConfigPair> c) {
        try {
            return JSONOBJECTMAPPER.writeValueAsString(c);
        } catch (JsonProcessingException e) {
            throw new RuntimeException(e);
        }
    }

    public Map<String, ConfigPair> getConfig() {
        return config;
    }

    public void setConfig(Map<String, ConfigPair> config) {
        this.config = config;
    }

    private Map<String, ConfigPair> config;
    private final Path configPath;
    private final Logger log;
    private final Path configFile;
    private final VersionsEnum versions;

    public ConfigManager(Path configPath, Logger log, VersionsEnum versions) {
        this.versions = versions;
        defConfig = new DefConfig(versions);
        this.log = log;
        configFile = configPath.resolve(FILE_NAME);
        this.configPath = configPath;
        config = load();
    }

    public Map<String, ConfigPair> load() {
        try {
            if (Files.exists(configFile)) {
                log.info("{} 配置加载", MinecraftMod.MOD_ID);
                return YALMOBJECTMAPPER.readValue(Files.readString(configFile), MODCONFIGTYPE);
            }
        } catch (Exception e) {
            log.error("Failed to load config", e);
        }
        return save(defConfig.getConfig());
    }

    public Map<String, ConfigPair> save() {
        return save(config);
    }

    public Map<String, ConfigPair> save(Map<String, ConfigPair> configs) {
        try {
            Files.writeString(configFile, YALMOBJECTMAPPER.writeValueAsString(configs));
            log.info("{} 配置已保存", MinecraftMod.MOD_ID);
        } catch (Exception e) {
            log.error("Failed to save config", e);
        }
        return configs;
    }

    public VersionsEnum getVersions() {
        return versions;
    }

    public DefConfig getDefConfig() {
        return defConfig;
    }
}
